package com.xzlf.task;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xzlf.domain.TFile;
import com.xzlf.service.TFileService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
//@Component
public class TestScheduleTask02 {

    //    private AtomicInteger taskNumber = new AtomicInteger(0);
    private AtomicInteger task1Number = new AtomicInteger(0);

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private TFileService tFileService;

    @Value("${task.lock.key1}")
    private String lockKey1;

    @Value("${task.lock.key2}")
    private String lockKey2;

    @Value("${task.lock.key3}")
    private String lockKey3;

    @Value("${task.lock.value1}")
    private String lockValue1;

    @Value("${task.lock.value2}")
    private String lockValue2;

    @Value("${task.lock.value3}")
    private String lockValue3;

    @Value("${server.name}")
    private String serverName;

    @Value("${job.execute.enable}")
    private boolean isExecute;

//    @Scheduled(cron = "${schedule.cron}")
    @Transactional
    public void test01() throws InterruptedException {
        if (!isExecute){
            log.info("任务01不执行");
            return;
        }
        //从RedissonClient取得Rlock实例
        RLock rLock = redissonClient.getLock(lockKey1);
        //尝试取锁，有效期为3s，到期后自动释放。如果取得锁继续执行。取锁失败则自旋。
        //使用rlock.tryLock（）方法，此方法也为尝试取锁，并返回boolean结果
        boolean lock = rLock.tryLock(2, 6, TimeUnit.SECONDS);
        if (!lock) {
            return;
        }
        try {
            log.info("我是：{}，抢到了锁，使用线程：{}，开始执行任务：task_1", serverName, Thread.currentThread().getName());
            TFile one = tFileService.getOne(new QueryWrapper<TFile>()
                    .select("id", "name")
                    .likeRight("name", "task_1_")
                    .orderByDesc("id").last("limit 1"));
            String name = (one == null ? null : one.getName());
            if (name == null) {
                name = "task_1_001";
            } else {
                int i = Integer.parseInt(name.substring(name.lastIndexOf('_') + 1));
                name = "task_1_" + String.format("%03d", (i + 1));
            }
            System.out.println("=================" + name);
            TFile tFile = new TFile(name, "task_1", "create By " + serverName);
            tFileService.save(tFile);
            TimeUnit.SECONDS.sleep(4);
            log.info("我是：{}，完成了任务task_1。", serverName);
        } finally {
            if (rLock.isLocked()) {// 是否还是锁定状态
                if (rLock.isHeldByCurrentThread()) {// 是否是当前执行线程的锁
                    log.info("我是：{}，完成了任务task_1，开始释放锁。", serverName);
                    rLock.unlock();
                }
            } else {
                log.info("我是：{}，没有抢到锁，无需释放。", serverName);
            }
        }
    }

    @Scheduled(cron = "${schedule.cron}")
    @Transactional
    public void test02() throws InterruptedException {
        if (!isExecute){
            log.info("任务02不执行");
            return;
        }
        //从RedissonClient取得Rlock实例
        RLock rLock = redissonClient.getLock(lockKey2);
        //尝试取锁，有效期为3s，到期后自动释放。如果取得锁继续执行。取锁失败则自旋。
        //使用rlock.tryLock（）方法，此方法也为尝试取锁，并返回boolean结果
        boolean lock = rLock.tryLock(2, 6, TimeUnit.SECONDS);
        if (!lock) {
            return;
        }
        try {
            log.info("我是：{}，抢到了锁，使用线程：{}，开始执行任务：task_2", serverName, Thread.currentThread().getName());
            TFile one = tFileService.getOne(new QueryWrapper<TFile>()
                    .select("id", "name")
                    .likeRight("name", "task_2_")
                    .orderByDesc("id").last("limit 1"));
            String name = one == null ? null : one.getName();
            if (name == null) {
                name = "task_2_001";
            } else {
                int i = Integer.parseInt(name.substring(name.lastIndexOf('_') + 1));
                name = "task_2_" + String.format("%03d", (i + 1));
            }
            System.out.println("=================" + name);
            TFile tFile = new TFile(name, "task_2", "create By " + serverName);
            tFileService.save(tFile);
            TimeUnit.SECONDS.sleep(4);
            log.info("我是：{}，完成了任务task_2。", serverName);
        } finally {
            if (rLock.isLocked()) {
                if (rLock.isHeldByCurrentThread()) {
                    log.info("我是：{}，完成了任务task_2，开始释放锁。", serverName);
                    rLock.unlock();
                }
            } else {
                log.info("我是：{}，没有抢到锁，无需释放。", serverName);
            }
        }
    }

    @Scheduled(cron = "${schedule.cron}")
    @Transactional
    public void test03() throws InterruptedException {

        if (!isExecute){
            log.info("任务03不执行");
            return;
        }
        //从RedissonClient取得Rlock实例
        RLock rLock = redissonClient.getLock(lockKey3);
        //尝试取锁，有效期为3s，到期后自动释放。如果取得锁继续执行。取锁失败则自旋。
        //使用rlock.tryLock（）方法，此方法也为尝试取锁，并返回boolean结果
        boolean lock = rLock.tryLock(2, 6, TimeUnit.SECONDS);
        if (!lock) {
            return;
        }
        try {
            log.info("我是：{}，抢到了锁，使用线程：{}，开始执行任务：task_3", serverName, Thread.currentThread().getName());
            TFile one = tFileService.getOne(new QueryWrapper<TFile>()
                    .select("id", "name")
                    .likeRight("name", "task_3_")
                    .orderByDesc("id").last("limit 1"));
            String name = one == null ? null : one.getName();
            if (name == null) {
                name = "task_3_001";
            } else {
                int i = Integer.parseInt(name.substring(name.lastIndexOf('_') + 1));
                name = "task_3_" + String.format("%03d", (i + 1));
            }
            System.out.println("=================" + name);
            TFile tFile = new TFile(name, "task_3", "create By " + serverName);
            tFileService.save(tFile);
            TimeUnit.SECONDS.sleep(4);
            log.info("我是：{}，完成了任务task_3。", serverName);
        } finally {
            if (rLock.isLocked()) {
                if (rLock.isHeldByCurrentThread()) {
                    log.info("我是：{}，完成了任务task_3，开始释放锁。", serverName);
                    rLock.unlock();
                }
            } else {
                log.info("我是：{}，没有抢到锁，无需释放。", serverName);
            }
        }
    }

    /*@Scheduled(fixedRate = 10000L, initialDelay = 10000L)
    public void test04() throws InterruptedException {
        TimeUnit.SECONDS.sleep(8);
        log.info("每隔10秒执行一次，当前线程：{}，当前执行次数：{}",Thread.currentThread().getName(), task1Number.incrementAndGet());
    }*/
}
